package com.example.wechat.login.task;

import com.example.wechat.login.config.SpeechHistoryConfig;
import com.example.wechat.login.mapper.SpeechRecognitionHistoryMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.stream.Stream;

/**
 * 语音历史记录清理任务
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SpeechHistoryCleanupTask {

    private final SpeechRecognitionHistoryMapper historyRepository;
    private final SpeechHistoryConfig historyConfig;

    /**
     * 每天凌晨2点执行清理任务
     */
    @Scheduled(cron = "0 0 2 * * ?")
    @Transactional
    public void cleanupExpiredHistory() {
        log.info("开始执行语音历史记录清理任务");

        try {
            // 清理过期的历史记录
            if (historyConfig.getHistoryRetentionDays() > 0) {
                LocalDateTime expirationDate = LocalDateTime.now().minusDays(historyConfig.getHistoryRetentionDays());
                log.info("清理 {} 之前的历史记录", expirationDate);

                // 删除数据库中的记录
                historyRepository.deleteByCreateTimeBefore(expirationDate);
            }

            // 清理孤立的音频文件（数据库中已不存在记录的文件）
            if (historyConfig.isSaveAudioFile()) {
                cleanupOrphanedAudioFiles();
            }

            // 如果配置了最大历史记录数量，则删除最早的记录
            if (historyConfig.getMaxHistoryCount() > 0) {
                long totalCount = historyRepository.count();
                if (totalCount > historyConfig.getMaxHistoryCount()) {
                    log.info("当前历史记录数量 {} 超过最大限制 {}, 清理最早的记录",
                            totalCount, historyConfig.getMaxHistoryCount());

                    // 这里可以实现删除最早的记录的逻辑
                    // 由于JPA Repository没有直接提供这样的方法，可能需要自定义查询或使用原生SQL
                }
            }

            log.info("语音历史记录清理任务完成");
        } catch (Exception e) {
            log.error("语音历史记录清理任务失败", e);
        }
    }

    /**
     * 清理孤立的音频文件
     */
    private void cleanupOrphanedAudioFiles() {
        Path storagePath = Paths.get(historyConfig.getFileStoragePath());
        if (!Files.exists(storagePath)) {
            return;
        }

        try (Stream<Path> files = Files.list(storagePath)) {
            files.filter(Files::isRegularFile).forEach(file -> {
                String fileName = file.getFileName().toString();
                // 检查文件是否在数据库中有对应记录
                boolean exists = historyRepository.existsByAudioFilePathContaining(fileName);
                if (!exists) {
                    try {
                        Files.delete(file);
                        log.info("删除孤立的音频文件: {}", file);
                    } catch (IOException e) {
                        log.error("删除孤立的音频文件失败: {}", file, e);
                    }
                }
            });
        } catch (IOException e) {
            log.error("清理孤立的音频文件失败", e);
        }
    }
}
